package com.example.myseekbar;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Scroller;

/**
 * 自定义弧形SeekBar 圆球部分
 * Created by Jaceli on 2016-04-28.
 */
public class SeekBarBallView extends View {

    private Paint paint;
    private Scroller scroller;
    private final int ballSize;
    private int ballColor;
    private static final int BALL_BACKGROUND_MODE_PIC = 1;
    private static final int BALL_BACKGROUND_MODE_COLOR = 2;
    private static final int BALL_BACKGROUND_MODE_XML = 3;
    private static final int BALL_BACKGROUND_MODE_DEFAULT = 4;
    private int ballBackgroundMode = BALL_BACKGROUND_MODE_DEFAULT;
    private Bitmap bitmapPaint;
    private Rect src;
    private Rect dst;
    private OnSmoothScrollListener listener;

    public SeekBarBallView(Context context, int ballSize, Drawable ballBackground) {
        super(context);
        this.ballColor = Color.RED;
        this.ballSize = ballSize;
        if (null != ballBackground) {
            // 设置了背景
            if (ballBackground instanceof BitmapDrawable) {
                // 设置了一张图片
                bitmapPaint = ((BitmapDrawable) ballBackground).getBitmap();
                ballBackgroundMode = BALL_BACKGROUND_MODE_PIC;
            } else if (ballBackground instanceof GradientDrawable) {
                // XML
                bitmapPaint = drawable2Bitmap(ballBackground);
                ballBackgroundMode = BALL_BACKGROUND_MODE_XML;
            } else if (ballBackground instanceof ColorDrawable) {
                // 色值
                this.ballColor = ((ColorDrawable) ballBackground).getColor();
                ballBackgroundMode = BALL_BACKGROUND_MODE_COLOR;
            } else {
                // 其他形式
                ballBackgroundMode = BALL_BACKGROUND_MODE_DEFAULT;
            }
        } else {
            // 没有设置背景
            ballBackgroundMode = BALL_BACKGROUND_MODE_DEFAULT;
        }
        init(context);
    }

    public SeekBarBallView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.ballColor = Color.RED;
        this.ballSize = 10;
        init(context);
    }

    private void init(Context context) {
        scroller = new Scroller(context);
        paint = new Paint();
        paint.setFlags(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.FILL);
        // 画摇杆
        if (BALL_BACKGROUND_MODE_PIC == ballBackgroundMode || BALL_BACKGROUND_MODE_XML == ballBackgroundMode) {
            // 指定图片绘制区域(原图大小)
            src = new Rect(0, 0, bitmapPaint.getWidth(), bitmapPaint.getHeight());
            // 指定图片在屏幕上显示的区域(ballSize大小)
            dst = new Rect(0, 0, ballSize, ballSize);
        } else if (BALL_BACKGROUND_MODE_COLOR == ballBackgroundMode) {
            // 色值
            paint.setColor(ballColor);
        } else {
            // 其他或者未设置
            paint.setColor(Color.RED);
        }
    }

    public void setListener(OnSmoothScrollListener listener) {
        this.listener = listener;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int spec = MeasureSpec.makeMeasureSpec(ballSize, MeasureSpec.EXACTLY);
        setMeasuredDimension(spec, spec);
    }

    // 使用之前设置的startScroll计算出的坐标，返给该函数，该函数调用回调描画小球
    @Override
    public void computeScroll() {
        if (scroller.computeScrollOffset()) {
            if (listener != null) {
                listener.onSmoothScroll(scroller.getCurrX(), scroller.getCurrY());
                postInvalidate();
            }
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // 画摇杆
        if (BALL_BACKGROUND_MODE_PIC == ballBackgroundMode || BALL_BACKGROUND_MODE_XML == ballBackgroundMode) {
            // 图片
            canvas.drawBitmap(bitmapPaint, src, dst, null);
        } else if (BALL_BACKGROUND_MODE_COLOR == ballBackgroundMode) {
            // 色值
            canvas.drawCircle((float) getMeasuredWidth() / 2, (float) getMeasuredWidth() / 2, (float) getMeasuredWidth() / 2, paint);
        } else {
            // 其他或者未设置
            canvas.drawCircle((float) getMeasuredWidth() / 2, (float) getMeasuredWidth() / 2, (float) getMeasuredWidth() / 2, paint);
        }
    }

    /**
     * 平滑滑动
     *
     * @param startX 起始值X
     * @param startY 起始值Y
     * @param dx     X滑动距离
     * @param dy     Y滑动距离
     */
    public void smoothScrollLevel(int startX, int startY, int dx, int dy) {
        scroller.startScroll(startX, startY, dx, dy, 500);
        postInvalidate();
    }

    public interface OnSmoothScrollListener {
        void onSmoothScroll(int currentX, int currentY);
    }

    /**
     * Drawable 转 Bitmap
     *
     * @param drawable Drawable
     * @return Bitmap
     */
    private Bitmap drawable2Bitmap(Drawable drawable) {
        // 取 drawable 的长宽
        int width = drawable.getIntrinsicWidth();
        int height = drawable.getIntrinsicHeight();
        // 取 drawable 的颜色格式
        Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
        // 建立对应 bitmap
        Bitmap bitmap = Bitmap.createBitmap(width, height, config);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, width, height);
        drawable.draw(canvas);
        return bitmap;
    }
}
